home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.alaska-software.com
/
2014.06.ftp.alaska-software.com.tar
/
ftp.alaska-software.com
/
3pp
/
mxsetup.old
/
{app}
/
Tooltip.prg
< prev
Wrap
Text File
|
2001-09-14
|
14KB
|
578 lines
//////////////////////////////////////////////////////////////////////
//
// TOOLTIP.PRG
//
// Copyright:
// Maniacc Software - 01/31/2000
// Modified by jpc - 02/23/2000 --- Made to handle up to 3 lines
// Modified by jpc - 07/11/2000 --- No line limit - use Memo Field
//
// Contents:
// Tooltip help system
//
//////////////////////////////////////////////////////////////////////
#include "Gra.ch"
#include "Xbp.ch"
#include "Appevent.ch"
#include "Font.ch"
#include "Dbstruct.ch"
#include "Common.ch"
#define nMaxLen 40
#define nNoTip xbeP_User + 12
#define xbeK_CTRL_ALT_E 852037
CLASS MxToolHelp FROM Thread
HIDDEN:
METHOD DisplayToolTip()
METHOD PaintTheTip()
METHOD EditTheTip()
EXPORTED:
VAR producerID
VAR oLastMotionXBP
VAR oLastTipXBP
VAR oBlockedXBP
VAR nLastTipTime
VAR aLastMotionPos
VAR oTip
VAR lTipIsShown
VAR nTipSensitivity
VAR lShowDefault
VAR ToolFileName
INLINE METHOD init(cToolFileName)
Default cToolFileName to "MTOOL"
::ToolFileName := cToolFileName
::nTipSensitivity := .5
::thread:init()
::producerID := ThreadID()
RETURN
EXPORTED:
METHOD execute()
METHOD atStart()
METHOD atEnd()
METHOD showTip()
METHOD hideTip()
METHOD editTip()
ENDCLASS
METHOD MxToolHelp:atStart()
::lTipIsShown := .F.
::oLastMotionXBP := NIL
::aLastMotionPos := NIL
::nLastTipTime := seconds()
/*
* The HELP Database and Index are located in the Current Drive &
* Directory. The Index expression is: PROG_NAME
*/
if !file(::ToolFileName + ".DBF")
MakeHelp(::ToolFileName)
use (::ToolFileName) alias TIP new exclusive
index on PROG_NAME to (::ToolFileName)
use
endif
use (::ToolFileName) index (::ToolFileName) alias TIP shared
RETURN
METHOD MxToolHelp:atEnd()
DbCloseAll()
RETURN
METHOD MxToolHelp:Execute(lDefault)
LOCAL nEvent, mp1:=0, mp2:=0, oXbp:=NIL
LOCAL nLastMotionTime := 0, lEdit := .F.
if lDefault==NIL
lDefault := .F.
endif
::lShowDefault := lDefault
DO WHILE .T.
Sleep( 20 )
nEvent := LastAppEvent(@mp1,@mp2,@oXbp,::producerID)
IF oXbp:isDerivedFrom("XbpIWindow")
oXbp := oXbp:setParent()
ENDIF
if nEvent == xbeM_LbClick .or. nEvent == nNoTip
::oBlockedXBP := oXbp
::hideTip()
LOOP
endif
if nEvent == xbeP_Keyboard.and.mp1==xbeK_CTRL_ALT_E
::editTip()
LOOP
ELSEIF (ValType(::oBlockedXBP)=="O" .AND. oXbp == ::oBlockedXBP )
LOOP
ENDIF
do while oXbp:isDerivedFrom("XbpStatic")
oXbp := oXbp:setParent()
enddo
IF(nEvent == xbeM_Motion)
::oBlockedXBP := NIL
IF ( ValType( ::oLastMotionXBP) == "O" .AND. oXbp == ::oLastMotionXBP )
IF( ::aLastMotionPos[1] == mp1[1] .AND. ;
::aLastMotionPos[2] == mp1[2] )
IF Seconds()-nLastMotionTime>::nTipSensitivity // .and. SetAppFocus()<>oXbp
::showTip()
ENDIF
ELSE
::aLastMotionPos := AClone(mp1)
nLastMotionTime := Seconds()
ENDIF
ELSEIF ( ValType(::oLastTipXBP) == "O" .AND. ;
oXbp:setParent() == ::oLastTipXBP:setParent() .AND. ;
oXbp != ::oLastTipXBP )
::hideTip()
::oLastMotionXBP := oXbp
::aLastMotionPos := AClone(mp1)
nLastMotionTime := Seconds()
IF ::nLastTipTime>0 .AND. Seconds()-::nLastTipTime<=0.5 .and. SetAppFocus()<>oXbp
::showTip()
ENDIF
ELSE
::oLastMotionXBP := oXbp
::aLastMotionPos := AClone(mp1)
nLastMotionTime := Seconds()
::hideTip()
ENDIF
ELSEIF nEvent != xbeP_Paint
IF oXbp==::oLastTipXBP .or. nEvent==xbeM_LbClick .or.nEvent == nNoTip
::oBlockedXBP := oXbp
ENDIF
::oLastMotionXBP := NIL
::hideTip()
ENDIF
ENDDO
RETURN
METHOD MxToolHelp:showTip()
IF(!::lTipIsShown)
::DisplayToolTip(::oLastMotionXBP)
::oLastTipXBP := ::oLastMotionXBP
::oBlockedXBP := NIL
ENDIF
RETURN
METHOD MxToolHelp:hideTip()
IF(::lTipIsShown)
::oTip:hide()
::oTip:destroy()
::lTipIsShown := .F.
::nLastTipTime := Seconds()
ENDIF
RETURN
METHOD MxToolHelp:DisplayToolTip(oXbpRequestingHint)
LOCAL cText := ""
LOCAL cID := "", cAlias := alias()
LOCAL aPos, aChildren, oParent, nChild, nChildren
IF (ValType(oXbpRequestingHint:helpLink)=="O" .and. ;
oXbpRequestingHint:helpLink:isDerivedFrom("ToolHelpLabel"))
cSeek := oXbpRequestingHint:cargo
if oXbpRequestingHint:isDerivedFrom("XbpSLE") .and. !oXbpRequestingHint:editable
cText := "This data is not editable at this time"
elseif oXbpRequestingHint:isDerivedFrom("XbpRadioButton")
if oXbpRequestingHint:editbuffer()
cText := "Unmark to Deactivate Option"
else
cText := "Mark to Activate Option"
endif
elseif oXbpRequestingHint:isDerivedFrom("XbpCheckBox")
if oXbpRequestingHint:editbuffer()
cText := "Uncheck box to Deactive Option"
else
cText := "Check Box to Activate Option"
endif
elseif cSeek <> NIL
go top
DBSeek(cSeek,.F.)
if found().and.alltrim(TIP->PROG_NAME)==alltrim(cSeek)
cText := Trim( TIP->T_STRING + TIP->T_MEMO )
else
cText := " "
endif
else
cText := " "
endif
ELSE
if ::lShowDefault
if oXbpRequestingHint:isDerivedFrom("XbpDialog");
.or.oXbpRequestingHint:isDerivedFrom("PBMenuBar")
elseif oXbpRequestingHint:isDerivedFrom("XbpComboBox")
cText := "Select from List"
elseif oXbpRequestingHint:isDerivedFrom("XbpSLE") .and. !oXbpRequestingHint:editable
cText := "This data is Automatic"
elseif oXbpRequestingHint:isDerivedFrom("XbpPushButton")
cText := "Click to Perform Function "
elseif oXbpRequestingHint:isDerivedFrom("MxPushButton");
.or.oXbpRequestingHint:setParent():isDerivedFrom("MxPushButton");
.or.oXbpRequestingHint:setParent():setParent():isDerivedFrom("MxPushButton")
cText := "Click to Perform Function "
elseif oXbpRequestingHint:isDerivedFrom("XbpRadioButton")
if oXbpRequestingHint:editbuffer()
cText := "Unmark to Deactivate Option"
else
cText := "Mark to Activate Option"
endif
elseif oXbpRequestingHint:isDerivedFrom("XbpCheckBox")
if oXbpRequestingHint:editbuffer()
cText := "Uncheck box to Deactive Option"
else
cText := "Check Box to Activate Option"
endif
else
cText := " "
endif
else
cText := " "
endif
ENDIF
/*
* Ok, now lets paint the TIP
*/
if !empty(cText)
aPos := calcAbsolutePosition(::aLastMotionPos,oXbpRequestingHint)
aPos[1] += 20
aPos[2] -= 15
::oTip := XbpStatic():new()
::oTip:options := XBPSTATIC_TYPE_FGNDFRAME
::oTip:create(AppDesktop(),AppDesktop(), aPos, { 0 , 0 })
::PaintTheTip(cText)
::oTip:show()
::lTipIsShown := .T.
else
::lTipIsShown := .F.
endif
RETURN(SELF)
METHOD MxToolHelp:PaintTheTip(cText)
LOCAL aAttr, oPS, oFont
LOCAL aPoints, nColor := 16, i, nHeight
LOCAL aSize := {0,0}, aPos := AppDesktop():currentSize()
LOCAL aOldPos := ::oTip:currentPos()
oPS := ::oTip:lockPS()
aText := Wrap(cText,nMaxLen)
oFont := XbpFont():new(oPS):create("9.Arial")
GraSetFont( oPS,oFont )
for i:=1 to len(aText)
aPoints := GraQueryTextBox( oPS, alltrim(aText[i]) )
if ((aPoints[3,1]-aPoints[1,1])+8)>aSize[1]
aSize[1] := (aPoints[3,1] - aPoints[1,1]) + 8
endif
if i==1
aSize[2] := (aPoints[1,2] - aPoints[2,2]) + 4
nHeight := aSize[2]-4
else
aSize[2] := aSize[2]+(aPoints[1,2]-aPoints[2,2])
endif
next i
::oTip:unlockPS()
::oTip:setSize(aSize,.F.)
if aOldPos[1]+aSize[1]>aPos[1]-5
aPos[1] := aPos[1]-aSize[1]-5
else
aPos[1] := aOldPos[1]
endif
if aPos[1]+aSize[1] >AppDeskTop():currentSize()[1]
aPos[1] := AppDeskTop():CurrentSize()[1] - 5 - aSize[1]
endif
if len(aText)>1
for i:=2 to len(aText)
aOldPos[2] := aOldPos[2]-nHeight
next i
endif
if aOldPos[2]<5
aPos[2] := 5
else
aPos[2] := aOldPos[2]
endif
if aPos[2] < 6
aPos[2] := 6
endif
::oTip:setPos(aPos,.F.)
oPS := ::oTip:lockPS()
GraSetFont( oPS,oFont )
oPS:setColorIndex(16,{255,255,210})
aAttr := Array( GRA_AA_COUNT )
aAttr [ GRA_AA_COLOR ] := nColor
GraSetAttrArea( oPS, aAttr )
GraBox( oPS, { 0, 0}, {aSize[1]-1, aSize[2]-1}, GRA_OUTLINEFILL, 6, 6 )
aPos := {4,aSize[2]-nHeight}
for i:=1 to len(aText)
GraStringAt( oPS, aPos, aText[i] )
aPos[2] := aPos[2]-nHeight
next i
::oTip:unLockPS( oPS)
RETURN(SELF)
METHOD MxToolHelp:editTip()
::EditTheTip(::oLastMotionXBP)
RETURN
METHOD MxToolHelp:EditTheTip(oXbpRequestingHint)
LOCAL cText := ""
LOCAL oFocus
LOCAL aPos, aChildren, oParent, nChild, nChildren
LOCAL cAlias := alias()
if ::oLastMotionXBP==NIL
return
endif
IF (ValType(oXbpRequestingHint:helpLink)=="O" .and. ;
oXbpRequestingHint:helpLink:isDerivedFrom("ToolHelpLabel"))
cSeek := oXbpRequestingHint:cargo
if oXbpRequestingHint:isDerivedFrom("XbpSLE") .and. !oXbpRequestingHint:editable
// Don't edit the tip (Automatic Data)
elseif oXbpRequestingHint:isDerivedFrom("XbpRadioButton")
//
elseif oXbpRequestingHint:isDerivedFrom("XbpCheckBox")
//
elseif cSeek <> NIL
nChild := 0
for i:=3 to 1 step -1
nChild := val(right(cSeek,i))
if nChild<>0
i:=1
endif
next i
select TIP
go top
DBSeek(cSeek,.F.)
if found() .and. alltrim(TIP->PROG_NAME) == cSeek
cText := Trim( TIP->T_STRING + TIP->T_MEMO )
rlock()
else
go top
locate for empty(PROG_NAME)
if !found()
append blank
else
rlock()
endif
replace PROG_NAME with cSeek
endif
cText := TipEdit(cText,nChild)
endif
ENDIF
RETURN
CLASS ToolHelpLabel
ENDCLASS
/*
* This function calculates the absolute position
* from a given position relative to an XbasePART
*/
STATIC FUNCTION calcAbsolutePosition(aPos,oXbp)
LOCAL aAbsPos := oXbp:CurrentPos()
LOCAL oParent := oXbp
LOCAL oDesktop := AppDesktop()
if oParent:isDerivedFrom("XbpComboBox") .and. oParent:type <> XBPCOMBO_SIMPLE
aAbsPos[2] := aAbsPos[2]+(oParent:currentSize()[2]-20)
endif
DO WHILE oParent <> oDesktop
oParent := oParent:setParent()
aAbsPos[1] += oParent:currentPos()[1]
aAbsPos[2] += oParent:currentPos()[2]
ENDDO
RETURN(aAbsPos)
FUNCTION TipEdit(cText,nChild)
LOCAL nEvent,mp1,mp2,oXbp
LOCAL oModal,oBtn,oLastFocus,oDa, lEdit := .T., aPos := {}, aSize
LOCAL cAlias := alias()
aSize := {376,190}
aPos := AppDeskTop():currentSize()
aPos[1] := (aPos[1]/2) - 188
aPos[2] := (aPos[2]/2) - 95
oModal := XbpDialog():new(AppDesktop(),SetAppWindow(),aPos,aSize)
oModal:sysmenu := .F.
oModal:taskList := .F.
oModal:titleBar := .F.
oModal:keyBoard := {|nKey| iif(nKey == xbeK_ESC,PostAppEvent(xbeP_Close,,,oModal),nil)}
oModal:create()
oModal:drawingArea:setColorBG(GRA_CLR_BLACK)
oModal:setFontCompoundName("10.Alaska CRT")
oModal:setModalState(XBP_DISP_APPMODAL)
oDa := oModal:drawingarea
oXbp := XbpStatic():new()
oXbp:caption := "Enter the Tip for Item: "+TIP->PROG_NAME
oXbp:SetFontCompoundName("12.Arial Bold")
oXbp:options := XBPSTATIC_TEXT_VCENTER
oXbp:create( oDa, , {10,150}, {350,20}, {{XBP_PP_FGCLR,GRA_CLR_WHITE }} )
oMLE := XbpMLE():new()
oMLE:editable := .T.
oMLE:datalink := { |x| IIf( x==NIL, cText, cText := x ) }
oMLE:SetColorBG( XBPSYSCLR_INFOBACKGROUND )
oMLE:SetFontCompoundName("10.Alaska CRT")
oMLE:clipSiblings := .T.
oMLE:tabstop := .T.
oMLE:HorizScroll := .F.
oMLE:create( oDa, , {10,40}, {350,100}, {{XBP_PP_INACTIVETEXT_FGCLR,GRA_CLR_BLACK }} )
oMLE:setdata()
oBtn := XBPPushButton():new( oModal:drawingArea ,oModal:drawingArea, {280,10}, {80,20}, { { XBP_PP_COMPOUNDNAME, "10.Alaska CRT" } } )
oBtn:caption := "SAVE"
oBtn:clipSiblings := .T.
oBtn:tabstop := .T.
oBtn:create()
oBtn:activate := { || PostAppEvent(xbeP_Close,,,oModal)}
oBtn := XBPPushButton():new( oModal:drawingArea ,oModal:drawingArea, {180,10}, {80,20}, { { XBP_PP_COMPOUNDNAME, "10.Alaska CRT" } } )
oBtn:caption := "Cancel"
oBtn:clipSiblings := .T.
oBtn:tabstop := .T.
oBtn:create()
oBtn:activate := { || PostAppEvent(xbeP_Close,,,oModal), lEdit := .F.}
oModal:show()
oLastFocus := SetAppFocus(oBtn)
SetAppFocus(oMLE)
nEvent := 0
DO WHILE nEvent <> xbeP_Close
nEvent := AppEvent(@mp1,@mp2,@oXbp)
if nEvent == xbeP_Keyboard .and. mp1 == xbeK_ESC
lEdit := .F.
exit
elseif nEvent == xbeP_Keyboard .and. SetAppFocus()<>oMLE .and. mp1 == xbeK_RETURN
exit
endif
oXbp:handleEvent(nEvent,mp1,mp2)
ENDDO
if lEdit
if rlock()
replace TIP->T_STRING with oMLE:editbuffer()
cTemp := substr(oMLE:editbuffer(),51)
if !empty(cTemp).or.!empty(TIP->T_MEMO)
replace T_MEMO with trim(cTemp)
endif
unlock
endif
endif
oModal:setModalState(XBP_DISP_MODELESS)
oModal:destroy()
SetAppFocus(oLastFocus)
RETURN cText
STATIC FUNCTION MakeHelp(cToolFileName)
LOCAL aStructure := { { "PROG_NAME" , "C", 15, 0 },;
{ "T_STRING" , "C", 50, 0 },;
{ "T_MEMO " , "M", 10, 0 } }
DbCreate( cToolFileName, aStructure, )
RETURN .T.
STATIC FUNCTION Wrap( cText )
LOCAL aText := {}
LOCAL nSpace := 0, i
LOCAL cSearch := chr(13)+" ,.?;:+->)}|\/*" // Possible Break characters
do while len(cText)>nMaxLen
for i := 1 to len(cSearch)
nSpace := rat(substr(cSearch,i,1),left(cText,nMaxLen))
if nSpace<>0
i:=len(cSearch)
endif
next i
if nSpace==0
nSpace := nMaxLen // Force a break if none of the characters in cSearch are found
endif
if substr(cText,nSpace,2)==chr(13)+chr(10)
nSpace := at(chr(13)+chr(10),left(cText,nMaxLen))
nSpace := nSpace-1
endif
if !empty(alltrim(left(cText,nSpace)))
aAdd(aText,strTran(left(cText,nSpace),chr(13)+chr(10)))
endif
cText := right(cText,len(cText)-nSpace)
if left(cText,2)==chr(13)+chr(10)
cText := right(cText,len(cText)-2)
endif
do while left(cText,2)==chr(13)+chr(10)
aAdd(aText," ")
cText := right(cText,len(cText)-2)
enddo
enddo
if !empty(cText)
aAdd(aText,strTran(cText,chr(13)+chr(10)))
endif
RETURN aText